#pragma once

//*****************************************************************************
// cList_DefCompare
//*****************************************************************************
template<class TYPE>
inline int cList_DefCompare(const TYPE *l, const TYPE *r) {
	if(*l > *r) {
		return 1;
	} else if(*l < *r) {
		return -1;
	} else {
		return 0;
	}
}

//*****************************************************************************
// cList_DefEquals
//*****************************************************************************
template<class TYPE>
inline bool cList_DefEquals(const TYPE *l, const TYPE *r) {
	return *l == *r;
}

//*****************************************************************************
// cList
//*****************************************************************************
template <class TYPE>
class cList {
public:
	typedef int Compare(const TYPE *, const TYPE *);
	typedef bool Equals(const TYPE *, const TYPE *);
	
	cList();
	cList(const cList<TYPE> &Src);
	
	enum ECopyCtor { CopyCtor };
	enum ESetCtor { SetCtor };
	
	cList(const ECopyCtor, const TYPE *Src, const int Count);		// cList L(cList::CopyCtor, s, 32);
	cList(const ESetCtor, TYPE *List, const int Count);				// cList U(cList::SetCtor, l, 100);
	explicit cList(const int Count);								// cList T(20);
	cList(const int Count, const TYPE &Fill);						// cList Z(20, 0);
	
	~cList();
	
	size_t Size() const;			// Total size of used for elements memory (bytes)
	size_t SizeCapacity() const;	// Total size of allocated memory (bytes)

	// Assignment operators
	void Copy(const cList<TYPE> &Src);
	void Copy(const TYPE *Src, const int Count);
	void Set(TYPE *List, const int Count);
	void operator = (const cList<TYPE> &Src);
	void Swap(cList<TYPE> &With);

	// Access operators
	const TYPE & operator [] (const int Index) const;
	TYPE & operator [] (const int Index);
	const TYPE & GetAt(const int Index) const;
	TYPE & GetAt(const int Index);
	const TYPE & GetLast() const;
	TYPE & GetLast();
	void SetAt(const int Index, const TYPE &Value);
	const TYPE * ToPtr() const; // Returns a const pointer to the list
	TYPE * ToPtr(); // Returns a pointer to the list
	void GetRange(const int Index, const int Count, cList<TYPE> *To) const;

	void Free(); // Removes all items from the list and frees all the space
	void FreeUnused(); // Resizes the list to exactly the number of elements it contains
	void FreeContents(); // Calls the destructor of all elements in the list

	int Count() const; // Gets the number of elements actually contained in the "cList"
	void SetCount(const int Count); // Sets the number of elements actually contained in the "cList"
	// Sets the number of elements actually contained in the "cList" and
	// initializes every element with specified value "Fill"
	void SetCount(int Count, const TYPE &Value);

	// Gets or sets the number of elements that the "cList" can contain
	int Capacity() const;
	void SetCapacity(const int Capacity);

	bool IsEmpty() const;
	void Clear();
	void Fill(const TYPE &Value);

	// Adds "Count" elements to the end of the list. Returns the index of the last added element.
	int Add(const TYPE &Value, const int Count = 1);

	void AddRange(const cList<TYPE> &Src); // Adds the elements of another "cList" object to the end of current
	void AddRange(const TYPE *Src, const int Count); // Adds "Count" elements of another list to the end of current

	// Inserts element to the list at the specified position with specified number of times
	void Insert(const int Index, const TYPE &Value, const int Count = 1);

	// Inserts the elements of another "cList" object into current at the specified position
	void InsertRange(const int Index, const cList<TYPE> &Src);

	// Insert the elements of another list of specified length at the specified position
	void InsertRange(const int Index, const TYPE *Src, const int Count);

	// Removes the first occurence of a specific object from the "cList" object.
	// Returns "true" if value was found; otherwise, false.
	bool Remove(const TYPE &Value, Equals *E = (Equals *)&cList_DefEquals);

	// cList<int> L;
	// ...
	// while(L.Remove(10, ZeroResidue)) {
	// }
	
	// Removes a range of elements from the "cList" object with specified number of elements to remove
	void RemoveAt(const int Index, const int Count = 1);
	
	void RemoveLast();
	
	// Searches for the specified object and returns the zero - based index of the first occurrence
	// within the entire "cList" object using the specified equals function
	int IndexOf(const TYPE &Value, Equals *E = (Equals *)&cList_DefEquals) const;
	
	// cList<cStr> L;
	// ...
	// int i = L.IndexOf("Tilda", cStr::EqualsNoCase);

	// Using the specified equals function searches for the specified object and returns the zero - based
	// index of the first occurrence within the range of elements in the "cList" object that
	// extends from the specified index to the last element
	int IndexOf(const TYPE &Value, const int StartIndex, Equals *E = (Equals *)&cList_DefEquals) const;

	// Searches for the specified "Value" and returns the zero - based index of the first occurrence
	// within the range of elements in the "cList" object that starts at the specified index and
	// contains the specified number of elements
	int IndexOf(const TYPE &Value, const int StartIndex, const int Count, Equals *E = (Equals *)&cList_DefEquals) const;

	// Searches for the specified "Value" and returns the zero - based index of the last occurrence
	// within the entire "cList" object
	int LastIndexOf(const TYPE &Value, Equals *E = (Equals *)&cList_DefEquals) const;

	// Searches for the specified "Value" and returns the zero - based index of the last occurrence
	// within the range of elements in the "cList" object that extends from the first element
	// to the specified index
	int LastIndexOf(const TYPE &Value, const int StartIndex, Equals *E = (Equals *)&cList_DefEquals) const;

	// Searches for the specified "Value" and returns the zero - based index of the last occurrence
	// within the range of elements in the "cList" object the contains the specified number of elements
	// and ends at the specified index
	int LastIndexOf(const TYPE &Value, const int StartIndex, const int Count, Equals *E = (Equals *)&cList_DefEquals) const;
	
	// Searches the entire sorted "cList" object for an element using the specified compare function and returns
	// the zero - based index, if "Value" is found; otherwise, -1
	int BinarySearch(const TYPE &Value, Compare *C = (Compare *)&cList_DefCompare) const;

	// cList<cStr> L;
	// ...
	// int i = L.BinarySearch("Over", cStr::CompareNoCase);

	// Searches the range of elements in the sorted "cList" object for an element using the specified
	// compare function and returns the zero - based index, if "Value" is found; otherwise, -1
	int BinarySearch(const int Index, const int Count, const TYPE &Value, Compare *C = (Compare *)&cList_DefCompare) const;

	// Determines whether an element is in the "cList" object using the specified equals function
	bool Contains(const TYPE &Value, Equals *E = (Equals *)&cList_DefEquals) const;

	// Determines using "IndexOf" function whether an element is in the "cList" object, and only if
	// it is not in the list, adds it. Returns the index of founded or added element.
	int AddUnique(const TYPE &Value, Equals *E = (Equals *)&cList_DefEquals);
	
	// cList<cStr> L;
	// ...
	// bool s = L.Contains("Over", cStr::EqualsNoCase);
	
	void Reverse();									// Reverses the order of the elements in the entire "cList" object
	void Reverse(const int Index, const int Count);	// Reverses the order of the elements in the specified range
	
	// Sorts the elements in the entire "cList" object using the specified compare function
	void Sort(Compare *C = (Compare *)&cList_DefCompare);

	// Sorts the elements in a range of elements in "cList" object using the specified compare function
	void Sort(const int Index, const int Count, Compare *C = (Compare *)&cList_DefCompare);
	
	void operator += (const TYPE &);
	void operator -= (const TYPE &);
	void operator *= (const TYPE &);
	void operator /= (const TYPE &);
	
	// cList<cVec3> L;
	// ...
	// L += cVec3(10, 20, 0);
	// L *= cVec3(20.0f);

protected:
	void Null();
	int m_Count, m_Capacity;
	TYPE *m_List;

	void EnsureCapacity(const int Capacity);
	void Resize(const int Capacity);
};

// cList<TYPE>::Null
template<class TYPE>
inline void cList<TYPE>::Null() {
	m_List = NULL;
	m_Count = m_Capacity = 0;
}


// cList<TYPE>.ctor : ()
template<class TYPE>
inline cList<TYPE>::cList() {
	Null();
}

// cList<TYPE>.ctor : (const cList<TYPE> &)
template<class TYPE>
inline cList<TYPE>::cList(const cList<TYPE> &Src) {
	Null();
	Copy(Src);
}

// cList<TYPE>.ctor : (const ECopyCtor, const TYPE *, const int)
template<class TYPE>
inline cList<TYPE>::cList(const ECopyCtor, const TYPE *Src, const int Count) {
	Null();
	Copy(Src, Count);
}

// cList<TYPE>.ctor : (const ESetCtor, TYPE *, const int)
template<class TYPE>
inline cList<TYPE>::cList(const ESetCtor, TYPE *Src, const int Count) {
	m_List = Src;
	m_Count = m_Capacity = Count;
}

// cList<TYPE>.ctor : (const int)
template<class TYPE>
inline cList<TYPE>::cList(const int Count) {
	Null();
	SetCount(Count);
}

// cList<TYPE>.ctor : (const int, const TYPE &)
template<class TYPE>
inline cList<TYPE>::cList(const int Count, const TYPE &Fill) {
	Null();
	SetCount(Count, Fill);
}

// cList<TYPE>.dtor
template<class TYPE>
inline cList<TYPE>::~cList() {
	Free();
}

// cList<TYPE>::Size
template<class TYPE>
inline size_t cList<TYPE>::Size() const {
	return m_Count * sizeof(TYPE);
}

// cList<TYPE>::SizeCapacity
template<class TYPE>
inline size_t cList<TYPE>::SizeCapacity() const {
	return m_Capacity * sizeof(TYPE);
}

//-----------------------------------------------------------------------------
// cList<TYPE>::Copy : void (const cList<TYPE> &)
//-----------------------------------------------------------------------------
template<class TYPE>
inline void cList<TYPE>::Copy(const cList<TYPE> &Src) {
	int i;

	EnsureCapacity(Src.m_Count);
	m_Count = Src.m_Count;
	
	for(i = 0; i < m_Count; i++) {
		m_List[i] = Src.m_List[i];
	}
}

//-----------------------------------------------------------------------------
// cList<TYPE>::Copy : (const TYPE *, const int)
//-----------------------------------------------------------------------------
template<class TYPE>
inline void cList<TYPE>::Copy(const TYPE *Src, const int Count) {
	int i;

	EnsureCapacity(Count);
	m_Count = Count;
	
	for(i = 0; i < m_Count; i++) {
		m_List[i] = Src[i];
	}
} // cList<TYPE>::Copy

//-----------------------------------------------------------------------------
// cList<TYPE>::Set : (TYPE *, const int)
//-----------------------------------------------------------------------------
template<class TYPE>
inline void cList<TYPE>::Set(TYPE *Src, const int Count) {
	Free();

	m_List = Src;
	m_Capacity = m_Count = Count;
}

// cList<TYPE>::operator =
template<class TYPE>
inline void cList<TYPE>::operator = (const cList<TYPE> &Src) {
	Copy(Src);
}

// cList<TYPE>::Swap
template<class TYPE>
inline void cList<TYPE>::Swap(cList<TYPE> &With) {
	cMath::Swap(m_Count, With.m_Count);
	cMath::Swap(m_Capacity, With.m_Capacity);
	cMath::Swap(m_List, With.m_List);
}

// cList<TYPE>::operator [] const
template<class TYPE>
inline const TYPE & cList<TYPE>::operator [] (const int Index) const {
	cAssert(Index >= 0);
	cAssert(Index < m_Count);
	return m_List[Index];
}

// cList<TYPE>::operator []
template<class TYPE>
inline TYPE & cList<TYPE>::operator [] (const int Index) {
	cAssert(Index >= 0);
	cAssert(Index < m_Count);
	return m_List[Index];
}

// cList<TYPE>::GetAt const
template<class TYPE>
inline const TYPE & cList<TYPE>::GetAt(int Index) const {
	cAssert(Index >= 0);
	cAssert(Index < m_Count);
	return m_List[Index];
}

// cList<TYPE>::GetAt
template<class TYPE>
inline TYPE & cList<TYPE>::GetAt(const int Index) {
	cAssert(Index >= 0);
	cAssert(Index < m_Count);
	return m_List[Index];
}

// cList<TYPE>::GetLast const
template<class TYPE>
inline const TYPE & cList<TYPE>::GetLast() const {
	cAssert(m_Count >= 1);
	return m_List[m_Count - 1];
}

// cList<TYPE>::GetLast
template<class TYPE>
inline TYPE & cList<TYPE>::GetLast() {
	cAssert(m_Count >= 1);
	return m_List[m_Count - 1];
}

// cList<TYPE>::SetAt
template<class TYPE>
inline void cList<TYPE>::SetAt(const int Index, const TYPE &Value) {
	cAssert(Index >= 0);
	cAssert(Index < m_Count);
	m_List[Index] = Value;
}

// cList<TYPE>::ToPtr() const
template<class TYPE>
inline const TYPE * cList<TYPE>::ToPtr() const {
	return m_List;
}

// cList<TYPE>::ToPtr
template<class TYPE>
inline TYPE * cList<TYPE>::ToPtr() {
	return m_List;
}

//------------------------------------------------------------------------------------------
// cList<TYPE>::GetRange
//------------------------------------------------------------------------------------------
template<class TYPE>
inline void cList<TYPE>::GetRange(const int Index, const int Count, cList<TYPE> *To) const {
	cAssert(Index >= 0);
	cAssert(Count >= 0);
	cAssert(Index + Count <= m_Count);
	
	int i;

	To->Clear();

	for(i = Index; i < Index + Count; i++) {
		To->Add(m_List[i]);
	}
} // cList<TYPE>::GetRange

// cList<TYPE>::Free
template<class TYPE>
inline void cList<TYPE>::Free() {
	if(m_List != NULL) {
		delete[] m_List;
		m_List = NULL;
	}
	m_Count = m_Capacity = 0;
}

// cList<TYPE>::FreeContents
template<class TYPE>
inline void cList<TYPE>::FreeContents() {
	int i;

	for(i = 0; i < m_Count; i++) {
		delete m_List[i];
		m_List[i] = NULL;
	}
}

// cList<TYPE>::FreeUnused
template<class TYPE>
inline void cList<TYPE>::FreeUnused() {
	Resize(m_Count);
}

// cList<TYPE>::Clear
template<class TYPE>
inline void cList<TYPE>::Clear() {
	m_Count = 0;
}

// cList<TYPE>::Count
template<class TYPE>
inline int cList<TYPE>::Count() const {
	return m_Count;
}

// cList<TYPE>::IsEmpty
template<class TYPE>
inline bool cList<TYPE>::IsEmpty() const {
	return m_Count < 1;
}

// cList<TYPE>::Capacity
template<class TYPE>
inline int cList<TYPE>::Capacity() const {
	return m_Capacity;
}

// cList<TYPE>::SetCapacity
template<class TYPE>
inline void cList<TYPE>::SetCapacity(const int Capacity) {
	Resize(Capacity);
}

//------------------------------------------------------------------------------------
// cList<TYPE>::Add
//-----------------------------------------------------------------------------
template<class TYPE>
inline int cList<TYPE>::Add(const TYPE &Value, const int Count) {
	cAssert(Count >= 0);

	int i;
	
	EnsureCapacity(m_Count + Count);
	for(i = 0; i < Count; i++) {
		m_List[m_Count] = Value;
		m_Count++;
	}
	return m_Count - 1;
} // cList<TYPE>::Add

//-----------------------------------------------------------------------------
// cList<TYPE>::AddRange : (const cList<TYPE> &)
//-----------------------------------------------------------------------------
template<class TYPE>
inline void cList<TYPE>::AddRange(const cList<TYPE> &Src) {
	int i;

	EnsureCapacity(m_Count + Src.m_Count);
	for(i = 0; i < Src.m_Count; i++) {
		m_List[m_Count] = Src.m_List[i];
		m_Count++;
	}
} // cList<TYPE>::AddRange

//-----------------------------------------------------------------------------
// cList<TYPE>::AddRange : (const TYPE *, const int)
//-----------------------------------------------------------------------------
template<class TYPE>
inline void cList<TYPE>::AddRange(const TYPE *Src, const int Count) {
	cAssert(Count >= 0);

	int i;
	
	EnsureCapacity(m_Count + Count);
	for(i = 0; i < Count; i++) {
		m_List[m_Count] = Src[i];
		m_Count++;
	}
} // cList<TYPE>::AddRange

//-------------------------------------------------------------------------------------------------------------
// cList<TYPE>::IndexOf
//-------------------------------------------------------------------------------------------------------------
template<class TYPE>
inline int cList<TYPE>::IndexOf(const TYPE &Value, const int StartIndex, const int Count, Equals *E) const {
	cAssert(StartIndex >= 0);
	cAssert(Count >= 0);
	cAssert(StartIndex + Count <= m_Count);
	
	int i;
	
	for(i = StartIndex; i < StartIndex + Count; i++) {
		if(E(&m_List[i], &Value)) {
			return i;
		}
	}
	
	return -1;
}

template<class TYPE>
inline int cList<TYPE>::IndexOf(const TYPE &Value, const int StartIndex, Equals *E) const {
	return IndexOf(Value, StartIndex, m_Count - StartIndex, E);
}

template<class TYPE>
inline int cList<TYPE>::IndexOf(const TYPE &Value, Equals *E) const {
	return IndexOf(Value, 0, m_Count, E);
}
// cList<TYPE>::IndexOf

//--------------------------------------------------------------------------------------------------------------
// cList<TYPE>::LastIndexOf
//--------------------------------------------------------------------------------------------------------------
template<class TYPE>
inline int cList<TYPE>::LastIndexOf(const TYPE &Value, Equals *E) const {
	return LastIndexOf(Value, m_Count - 1, m_Count, E);
}

template<class TYPE>
inline int cList<TYPE>::LastIndexOf(const TYPE &Value, const int StartIndex, Equals *E) const {
	return LastIndexOf(Value, StartIndex, StartIndex + 1, E);
}

template<class TYPE>
inline int cList<TYPE>::LastIndexOf(const TYPE &Value, const int StartIndex, const int Count, Equals *E) const {
	if(m_Count == 0) {
		cAssert(StartIndex >= -1);
		cAssert(StartIndex <= 0);
		cAssert(Count >= 0);
		return -1;
	}
	
	cAssert(StartIndex >= 0);
	cAssert(StartIndex < m_Count);
	cAssert(Count >= 0);
	cAssert(Count <= StartIndex + 1);
	
	int i, i0;
	
	i0 = StartIndex - Count + 1;
	for(i = StartIndex; i >= i0; i--) {
		if(E(&m_List[i], &Value)) {
			return i;
		}
	}

	return -1;
} // cList<TYPE>::LastIndexOf

//------------------------------------------------------------------------------------------------------------
// cList<TYPE>::BinarySearch
//------------------------------------------------------------------------------------------------------------
template<class TYPE>
inline int cList<TYPE>::BinarySearch(const int Index, const int Count, const TYPE &Value, Compare *C) const {
	cAssert(Index >= 0);
	cAssert(Count >= 0);
	cAssert(Index + Count <= m_Count);

	int l, r, m;
	
	if(Count > 0) {
		l = 0;
		r = Index + Count - 1;
		while(l < r) {
			m = (l + r) / 2;
			if(C(&Value, &GetAt(m)) <= 0) {
				r = m;
			} else {
				l = m + 1;
			}
		}
		if(C(&Value, &GetAt(l)) == 0) {
			return l;
		}
	}
	
	return -1;
}

template<class TYPE>
inline int cList<TYPE>::BinarySearch(const TYPE &Value, Compare *C) const {
	return BinarySearch(0, m_Count, Value, C);
}
// cList<TYPE>::BinarySearch

//-----------------------------------------------------------------------------
// cList<TYPE>::Contains
//-----------------------------------------------------------------------------
template<class TYPE>
inline bool cList<TYPE>::Contains(const TYPE &Value, Equals *E) const {
	int i;
	
	for(i = 0; i < m_Count; i++) {
		if(E(&m_List[i], &Value)) {
			return true;
		}
	}
	return false;
} // cList<TYPE>::Contains

// cList<TYPE>::AddUnique
template<class TYPE>
inline int cList<TYPE>::AddUnique(const TYPE &Value, Equals *E) {
	int i = IndexOf(Value, E);
	if(-1 == i) {
		i = Add(Value);
	}
	return i;
}

//-----------------------------------------------------------------------------
// cList<TYPE>::RemoveAt
//-----------------------------------------------------------------------------
template<class TYPE>
inline void cList<TYPE>::RemoveAt(const int Index, const int Count) {
	cAssert(Index >= 0);
	cAssert(Count >= 0);
	cAssert(Index + Count <= m_Count);

	int i;
	
	m_Count -= Count;
	for(i = Index; i < m_Count; i++) {
		m_List[i] = m_List[i + Count];
	}
} // cList<TYPE>::RemoveAt

// cList<TYPE>::RemoveLast
template<class TYPE>
inline void cList<TYPE>::RemoveLast() {
	cAssert(m_Count >= 1);
	m_Count--;
}

//-----------------------------------------------------------------------------
// cList<TYPE>::Remove
//-----------------------------------------------------------------------------
template<class TYPE>
inline bool cList<TYPE>::Remove(const TYPE &Value, Equals *E) {
	int Index = IndexOf(Value, E);
	if(Index >= 0) {
		RemoveAt(Index);
		return true;
	}
	return false;
} // cList<TYPE>::Remove

//-----------------------------------------------------------------------------------
// cList<TYPE>::Insert
//-----------------------------------------------------------------------------------
template<class TYPE>
inline void cList<TYPE>::Insert(const int Index, const TYPE &Value, const int Count) {
	cAssert(Index >= 0);
	cAssert(Index <= m_Count);
	cAssert(Count >= 0);
	
	int i;

	EnsureCapacity(m_Count + Count);
	for(i = m_Count - 1 + Count; i >= Index + Count; i--) {
		m_List[i] = m_List[i - Count];
	}
	m_Count += Count;

	cAssert(Index + Count <= m_Count);
	for(i = 0; i < Count; i++) {
		m_List[Index + i] = Value;
	}
} // cList<TYPE>::Insert

//-----------------------------------------------------------------------------
// cList<TYPE>::InsertRange : void (const int, const cList<TYPE> &)
//-----------------------------------------------------------------------------
template<class TYPE>
inline void cList<TYPE>::InsertRange(const int Index, const cList<TYPE> &Src) {
	cAssert(Index >= 0);
	cAssert(Index <= m_Count);
	
	int i;

	EnsureCapacity(m_Count + Src.m_Count);
	for(i = m_Count - 1 + Src.m_Count; i >= Index + Src.m_Count; i--) {
		m_List[i] = m_List[i - Src.m_Count];
	}
	m_Count += Src.m_Count;

	cAssert(Index + Src.m_Count <= m_Count);
	for(i = 0; i < Src.m_Count; i++) {
		m_List[Index + i] = Src.m_List[i];
	}
} // cList<TYPE>::InsertRange

//---------------------------------------------------------------------------------------
// cList<TYPE>::InsertRange : void (const int, const TYPE *, const int)
//---------------------------------------------------------------------------------------
template<class TYPE>
inline void cList<TYPE>::InsertRange(const int Index, const TYPE *Src, const int Count) {
	cAssert(Index >= 0);
	cAssert(Index <= m_Count);
	cAssert(Count >= 0);

	int i;
	
	EnsureCapacity(m_Count + Count);
	for(i = m_Count - 1 + Count; i >= Index + Count; i--) {
		m_List[i] = m_List[i - Count];
	}
	m_Count += Count;

	cAssert(Index + Count <= m_Count);
	for(i = 0; i < Count; i++) {
		m_List[Index + i] = Src[i];
	}
} // cList<TYPE>::InsertRange

//-----------------------------------------------------------------------------
// cList<TYPE>::Reverse : void (const int, const int)
//-----------------------------------------------------------------------------
template<class TYPE>
inline void cList<TYPE>::Reverse(const int Index, const int Count) {
	cAssert(Index >= 0);
	cAssert(Count >= 0);
	cAssert(Index + Count <= m_Count);

	int i, h;

	if(Count > 1) {
		h = Count / 2;
		for(i = 0; i < h; i++) {
			cMath::Swap(Index + i, Index + Count - 1 - i);
		}
	}
}

template<class TYPE>
inline void cList<TYPE>::Reverse() {
	Reverse(0, m_Count);
}
// cList<TYPE>::Reverse

//-----------------------------------------------------------------------------
// cList<TYPE>::Resize
//-----------------------------------------------------------------------------
template<class TYPE>
inline void cList<TYPE>::Resize(const int Capacity) {
	cAssert(Capacity >= 0);

	int i;
	TYPE *L = NULL;

	if(Capacity <= 0) {
		Free();
		return;
	}
	
	if(Capacity == m_Capacity) {
		return;
	}
	
	L = m_List;
	m_Capacity = Capacity;
	if(m_Capacity < m_Count) {
		m_Count = m_Capacity;
	}

	m_List = new TYPE[m_Capacity];
	for(i = 0; i < m_Count; i++) {
		m_List[i] = L[i];
	}
	
	if(L != NULL) {
		delete[] L;
	}
} // cList<TYPE>::Resize

//-----------------------------------------------------------------------------
// cList<TYPE>::EnsureCapacity
//-----------------------------------------------------------------------------
template<class TYPE>
inline void cList<TYPE>::EnsureCapacity(const int Capacity) {
	int S = 0;
	
	if(Capacity >= m_Capacity) {
		S = Capacity + 32 + m_Capacity / 2;
		Resize(S);
	}
} // cList<TYPE>::EnsureCapacity

// cList<TYPE>::SetCount : void (const int)
template<class TYPE>
inline void cList<TYPE>::SetCount(const int Count) {
	cAssert(Count >= 0);
	EnsureCapacity(Count);
	m_Count = Count;
}

// cList<TYPE>::Fill
template<class TYPE>
inline void cList<TYPE>::Fill(const TYPE &Value) {
	int i;

	for(i = 0; i < m_Count; i++) {
		m_List[i] = Value;
	}
}

// cList<TYPE>::SetCount : void (const int, const TYPE &)
template<class TYPE>
inline void cList<TYPE>::SetCount(const int Count, const TYPE &Value) {
	SetCount(Count);
	Fill(Value);
}

//-----------------------------------------------------------------------------
// cList<TYPE>::Sort
//-----------------------------------------------------------------------------
template<class TYPE>
inline void cList<TYPE>::Sort(const int Index, const int Count, Compare *C) {
	cAssert(Index >= 0);
	cAssert(Count >= 0);
	cAssert(Index + Count <= m_Count);
	
	int i = 0, j = 0, M = 0;
	bool f = false;
	TYPE K;
	
	M = Count / 2;
	while(M >= 1) {
		for(i = M; i < Count; i++) {
			K = GetAt(i + Index);
			j = i - M;
			f = false;
			while(j >= 0 && !f) {
				if(C(&K, &GetAt(j + Index)) < 0) {
					SetAt(j + M + Index, GetAt(j + Index));
					j -= M;
				} else {
					f = true;
				}
			}
			SetAt(j + M + Index, K);
		}
		M /= 2;
	}
}

template<class TYPE>
void cList<TYPE>::Sort(Compare *C) {
	Sort(0, m_Count, C);
}
// cList<TYPE>::Sort

// cList<Type>::operator +=
template<class Type>
inline void cList<Type>::operator += (const Type &u) {
	for(int i = 0; i < m_Count; i++) {
		m_List[i] += u;
	}
}

// cList<Type>::operator -=
template<class Type>
inline void cList<Type>::operator -= (const Type &u) {
	for(int i = 0; i < m_Count; i++) {
		m_List[i] -= u;
	}
}

// cList<Type>::operator *=
template<class Type>
inline void cList<Type>::operator *= (const Type &u) {
	for(int i = 0; i < m_Count; i++) {
		m_List[i] *= u;
	}
}

// cList<Type>::operator /=
template<class Type>
inline void cList<Type>::operator /= (const Type &u) {
	for(int i = 0; i < m_Count; i++) {
		m_List[i] /= u;
	}
}